package com.shiyi.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.ServiceException;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.StorageClass;
import com.shiyi.config.OssConfig;
import com.shiyi.dto.OssUrlDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;


/**
 * @author : leishuai
 * description: 阿里云OSS文件相关工具类
 * date : 2023/2/10  9:22
 **/
@Slf4j
@Component
public class OssUtils {

    @Resource
    private OssConfig ossConfig;

    /**
     * oss单文件上传
     *
     * @param multipartFiles multipartFiles
     * @return 上传成功返回访问地址 及文件名
     */
    public List<OssUrlDTO> uploadSingleFileToOss(MultipartFile[] multipartFiles) {
        List<OssUrlDTO> OssUrlDTOs = new ArrayList<>();
        //返回文件在oss上请求路径
        String url = "";
        log.info("OSS Started");
        // 生成OSSClient，您可以指定一些参数，详见“SDK手册 > Java-SDK > 初始化”，
        OSS ossClient = new OSSClientBuilder().build(ossConfig.getEND_POINT(), ossConfig.getACCESS_KEY_ID(), ossConfig.getACCESS_KEY_SECRET());
        try {
            // 判断Bucket是否存在。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
            if (ossClient.doesBucketExist(ossConfig.getBUCKET_NAME())) {
                log.info("您已经创建Bucket：{}", ossConfig.getBUCKET_NAME());
            } else {
                log.info("您的Bucket不存在，创建Bucket：{}。", ossConfig.getBUCKET_NAME());
                // 创建Bucket。详细请参看“SDK手册 > Java-SDK > 管理Bucket”。
                ossClient.createBucket(ossConfig.getBUCKET_NAME());
            }

            for (MultipartFile multipartFile : multipartFiles) {
                //获取文件后缀
                String filename = multipartFile.getOriginalFilename();
                if (StringUtils.isBlank(filename)) {
                    throw new ServiceException("文件类型未知");
                }
                String suffix = filename.substring(filename.lastIndexOf("."));
                //随机生成文件名
                String generatedFileName = getGeneratedFileName();
                //oss该文件的完整路径,vms项目文件夹名+当前日期文件夹+“/”+文件名+后缀名
                String fileKey = ossConfig.getFOLDER() + LocalDate.now() + "/" + generatedFileName + suffix;
                // 创建PutObjectRequest对象。
                PutObjectRequest putObjectRequest = new PutObjectRequest(ossConfig.getBUCKET_NAME(), fileKey, multipartFile.getInputStream());
                // 上传时设置存储类型和访问权限
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
                metadata.setObjectAcl(CannedAccessControlList.PublicRead);
                String contentType = getContentType(suffix);
                //根据后缀名设置oss的http头
                metadata.setContentType(contentType);
                putObjectRequest.setMetadata(metadata);
                // 上传文件。
                ossClient.putObject(putObjectRequest);
                log.info("Object：{}存入OSS成功。", fileKey);
                url = "http://" + ossConfig.getBUCKET_NAME() + "." + ossConfig.getEND_POINT() + "/" + fileKey;
                log.info("访问地址：{}", url);

                OssUrlDTO OssUrlDTO = new OssUrlDTO();

                url = "http://" + ossConfig.getACCESS_ADDRESS() + "/" + fileKey;
                log.info("域名访问地址：{}", url);

                OssUrlDTO.setUrl(url).setFolderName(LocalDate.now() + "").setFileName(generatedFileName + suffix);
                OssUrlDTOs.add(OssUrlDTO);
            }
        } catch (OSSException oe) {
            log.error(oe.getMessage());
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return OssUrlDTOs;
    }


    /**
     * 设置oss文件http头，使其在线预览
     *
     * @param FilenameExtension FilenameExtension
     * @return String
     */
    public static String getContentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return null;
    }

    /**
     * 获取文件随机生成名称
     *
     * @return 文件名
     */
    public static String getGeneratedFileName() {
        Long timeMillis = System.currentTimeMillis();
        String uuidStr = UUID.randomUUID().toString();
        uuidStr = uuidStr.split("-")[0];
        return (timeMillis + "-" + uuidStr);
    }

}